package com.coderman.generator;

import lombok.extern.slf4j.Slf4j;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.mybatis.generator.internal.NullProgressCallback;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class CodeGenerator {

    public static void main(String[] args) throws Exception {
        generator();
    }

    private static final String PACKAGE_BASE = "com.coderman";//指定包

    private static final String PACKAGE_ENTITY = PACKAGE_BASE + ".common.model.student";//指定实体类的包路径

    private static final String PACKAGE_MAPPER = PACKAGE_BASE + ".business.mapper";//指定mapper类的包路径

    private static final String PACKAGE_SERVICE = PACKAGE_BASE + ".business.service";//指定service的包路径

    private static final String PACKAGE_SERVICE_IMPL = PACKAGE_SERVICE + ".imp";//指定serviceImpl的包路径


    private static String PATH_PROJECT = System.getProperty("user.dir");//获取程序的当前路径

    private static String PATH_ENTITY = PATH_PROJECT + "/src/main/java" + packageConvertPath(PACKAGE_ENTITY); //entity文件路径

    private static String PATH_MAPPER = PATH_PROJECT + "/src/main/java" + packageConvertPath(PACKAGE_MAPPER); //Mapper文件路径

    private static String PATH_MAPPER_XML = PATH_PROJECT + "/src/main/resources/mapper/biz"; //Mapper xml文件路径

    private static String PATH_SERVICE = PATH_PROJECT + "/src/main/java" + packageConvertPath(PACKAGE_SERVICE); //Service文件路径

    private static String PATH_SERVICE_IMPL = PATH_PROJECT + "/src/main/java" + packageConvertPath(PACKAGE_SERVICE_IMPL); //ServiceIMPL文件路径


    private static void generator() throws Exception {
        //执行过程中的警告信息
        List<String> warnings = new ArrayList<>();
        //生成的代码重复时，覆盖原代码
        boolean overwrite = true;
        //配置信息
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(getResourceAsStream("mybatis-generator.xml"));
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);

        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        //执行生成代码
        myBatisGenerator.generate(new NullProgressCallback() {
            @Override
            public void startTask(String taskName) {
                String regex = "Saving file ";
                if (!taskName.contains(regex)) {
                    return;
                }
                String fileName = taskName.replaceAll(regex, "");

                FileType fileType = getFileType(fileName);
                boolean isExists = checkFileExists(fileType, fileName);

                // 当文件存在时 只覆盖entity
                if (isExists && (fileType != FileType.ENTITY && fileType != FileType.MAPPERXML)) {
                    throw new RuntimeException(fileName + "存在不覆盖");
                }
            }

        });
        for (String warning : warnings) {
            //打印日志
            log.debug(warning);
        }
    }

    //检查文件是否存在的方法
    private static boolean checkFileExists(FileType fileType, String fileName) {

        String filePath = "";
        switch (fileType) {
            case ENTITY:
                filePath = PATH_ENTITY;
                break;
            case MAPPER:
                filePath = PATH_MAPPER;
                break;
            case SERVICE:
                filePath = PATH_SERVICE;
                break;
            case MAPPERXML:
                filePath = PATH_MAPPER_XML;
                break;
            case SERVICEIMPL:
                filePath = PATH_SERVICE_IMPL;
                break;
            default:
                return false;
        }

        File file = new File(filePath + fileName);

        return file.exists();
    }

    //检查文件类型
    private static FileType getFileType(String fileName) {
        if (fileName.contains("Mapper.xml")) {
            return FileType.MAPPERXML;
        }
        if (fileName.contains("Mapper.java")) {
            return FileType.MAPPER;
        }
        if (fileName.contains("Service.java")) {
            return FileType.SERVICE;
        }
        if (fileName.contains("ServiceImpl.java")) {
            return FileType.SERVICEIMPL;
        }
        if (fileName.contains(".java")) {
            return FileType.ENTITY;
        }

        return FileType.OTHER;
    }

    //根据路径将文件资源转换为流的形式
    private static InputStream getResourceAsStream(String path) {
        return Thread.currentThread().getContextClassLoader().getResourceAsStream(path);
    }

    //将包转换为路径
    private static String packageConvertPath(String packageName) {
        return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
    }

    enum FileType {
        MAPPER, MAPPERXML, ENTITY, SERVICE, SERVICEIMPL, OTHER
    }

}

